﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZeroBug.EasyFlow.Core;
using ZeroBug.EasyFlow.Machine;
using ZeroBug.EasyFlow.Motion;

namespace ZeroBug.EasyFlow.Step
{
    public class SensorOperateStep : IStep
    {
        public bool IsSingleRun { get; set; }
        public bool IgnoreChildren { get; set; }
        public string Icon { get; set; } = "Rss";
        public int ChildrenIndex { get; set; }
        public Core.Step? NextStep { get; set; }

        VariableExpression isAsyncRun;
        VariableExpression sensorNames;
        VariableExpression level;
        VariableExpression timeOut;
        VariableExpression bounceTime;
        public bool Compile(FlowBase flow, Core.Step step, out string errInfo)
        {
            errInfo = string.Empty;

            if (!step.Parameters.ContainsKey("SensorNames"))
            {
                errInfo = "不存在SensorNames变量";
                return false;
            }
            sensorNames = step.Parameters["SensorNames"];

            if (!step.Parameters.ContainsKey("Level"))
            {
                errInfo = "不存在Level变量";
                return false;
            }
            level = step.Parameters["Level"];

            if (!step.Parameters.ContainsKey("TimeOut"))
            {
                errInfo = "不存在TimeOut变量";
                return false;
            }
            timeOut = step.Parameters["TimeOut"];

            if (!step.Parameters.ContainsKey("BounceTime"))
            {
                bounceTime = new VariableExpression()
                {
                    ExpressionDealVarType = VariableType.Numeric,
                    Expressions = new List<string>() { "0" },
                };
            }
            else
                bounceTime = step.Parameters["BounceTime"];

            if (step.Parameters.ContainsKey("AsyncRun"))
            {
                isAsyncRun = step.Parameters["AsyncRun"];
            }

            return true;
        }

        public object GetForm()
        {
            throw new NotImplementedException();
        }

        public StepInfo GetInfo()
        {
            StepInfo info = new StepInfo();
            info.StepName = "SensorOperate";
            info.Group = StepGroup.Motion;
            info.ImagePath = "pack://application:,,,/ZeroBug.EasyFlow.Step;component/Images/条件.png";
            return info;
        }

        public void OnChildrenEnter()
        {

        }

        public void OnChildrenLeave()
        {

        }

        public bool Prepare(FlowBase flow, Core.Step step, out string errInfo)
        {
            errInfo = string.Empty;
            return true;
        }

        public void RegisterVariables(FlowBase flow, Core.Step step)
        {

        }

        public StepResult Run(FlowBase flow, Core.Step step, out string errInfo)
        {
            errInfo = string.Empty;
            //防止在其他地方被改过  需要考虑放在哪里这一步
            IsSingleRun = false;

            Variable sensor = sensorNames.GetEquivalent();
            Sensor? s = LocalMachine.Services.GetService<MachineResource<Sensor, IDigitalIO>>()?.Value[sensor[0]];
            int to = Convert.ToInt32(timeOut.GetEquivalent()[0]);
            int bt = Convert.ToInt32(bounceTime.GetEquivalent()[0]);

            bool isIgnore = true;
            SenseType type = (SenseType)Convert.ToInt32(level.GetEquivalent()[0]);
            switch(type)
            {
                case SenseType.On:
                    if (!s.WaitOn(to, true, bt))
                        isIgnore = false;
                    break;
                case SenseType.Off:
                    if (!s.WaitOn(to, false, bt))
                        isIgnore = false;
                    break;
                case SenseType.Off2On:
                    break;
                case SenseType.On2Off:
                    break;
            }
            IgnoreChildren = isIgnore;
            return StepResult.Success;
        }

        public string GetTip(Core.Step step)
        {
            return "";
        }

        public (SerializableDictionary<string, VariableExpression>, List<VariableJudge>) GetParametersAndConditions()
        {
            throw new NotImplementedException();
        }

        public void UnRegisterVariables(FlowBase flow, Core.Step step)
        {
        }
    }
    public enum SenseType
    {
        [Description("感应到")]
        On = 0,
        [Description("感应不到")]
        Off,
        [Description("从感应不到变成感应到的跳变")]
        Off2On,
        [Description("从感应到变成感应不到的跳变")]
        On2Off,
    }
}
